package cn.tedu.fy.pethome.filter;


import cn.tedu.fy.pethome.pojo.dto.AdminLoginDTO;
import cn.tedu.fy.pethome.security.LoginPrincipal;
import cn.tedu.fy.pethome.util.JwtUtil;
import cn.tedu.fy.pethome.web.JsonResult;
import cn.tedu.fy.pethome.web.ServiceCode;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import io.jsonwebtoken.lang.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Component
@Slf4j
public class JwtAuthorizationFilter extends OncePerRequestFilter {


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
      log.debug("jwt过滤器开始处理jwt");
      //清理之前Security的jwt，防止客户端未持有jwt也能访问服务器
        SecurityContextHolder.clearContext();

        String jwt = request.getHeader("Authorization");
        if(!Strings.hasText(jwt)){
            log.debug("没有jwt");
            filterChain.doFilter(request,response);
            return;
        }

        //解析jwt
        Claims claims = JwtUtil.parseJwt(jwt);

        //获得持有jwt的相关信息
        // bug fix:
        Long id = Long.parseLong(claims.get("id").toString());
        String username = (String) claims.get("username");
        String authoritiesString = (String) claims.get("authorities");
        log.debug("过滤器解析出来的用户id为{}",id);
        log.debug("过滤器解析出的用户名为{}",username);
        log.debug("过滤器解析出的权限为{}",authoritiesString);
        //将权限String转换为可用的集合类型
        List<SimpleGrantedAuthority> authorities =
                JSON.parseArray(authoritiesString, SimpleGrantedAuthority.class);

        //当事人
        LoginPrincipal principal = new LoginPrincipal();
        principal.setId(id);
        principal.setUsername(username);


        //准备认证信息
        Authentication authentication =
                new UsernamePasswordAuthenticationToken(principal,null,authorities);
        log.debug("即将放入上下文的认证信息为{}",authentication);
        //将认证信息放入security上下文容器中，告诉框架我已经是登陆状态可以访问
        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authentication);
        //放行
        filterChain.doFilter(request,response);

    }
}
